package com.warom.sdg.ui.activity;

import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.warom.sdg.R;
import com.warom.sdg.callback.PlcDataListener;
import com.warom.sdg.util.ModbusRtuHelper;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Modbus RTU通信测试Activity
 * 用于测试和演示使用串口进行Modbus RTU通信
 */
public class ModbusRtuDemoActivity extends AppCompatActivity {
    private static final String TAG = "ModbusRtuDemoActivity";
    
    // 定义Modbus地址范围
    private static final int COIL_START = 1;             // 00001
    private static final int COIL_END = 9999;            // 09999
    private static final int DISCRETE_INPUT_START = 10001;
    private static final int DISCRETE_INPUT_END = 19999;
    private static final int INPUT_REGISTER_START = 30001;
    private static final int INPUT_REGISTER_END = 39999;
    private static final int HOLDING_REGISTER_START = 40001;
    private static final int HOLDING_REGISTER_END = 49999;
    
    // 常用的串口路径
    private static final String[] SERIAL_PORT_PATHS = {
        "/C5.CoM",
        "/dev/ttyS1",
        "/dev/ttyS2",
        "/dev/ttyS3",
        "/dev/ttyUSB0",
        "/dev/ttyUSB1",
        "/dev/ttyACM0",
        "/dev/ttymxc0",
        "/dev/ttymxc1",
        "/dev/ttymxc2"
    };
    
    // 常用波特率
    private static final Integer[] BAUD_RATES = {
        1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
    };
    
    // UI组件
    private Spinner spSerialPort;
    private Spinner spBaudRate;
    private EditText etDataBits, etStopBits, etParity;
    private EditText etReadAddress, etReadCount, etReadUnitId;
    private EditText etWriteAddress, etWriteValue, etWriteUnitId;
    private Button btnConnect, btnDisconnect, btnRead, btnWrite;
    private Button btnClearLog;
    private TextView tvLog;
    
    // Modbus RTU通信帮助类
    private ModbusRtuHelper modbusHelper;
    private boolean isConnected = false;
    
    // 记录最近一次读取的数据和地址
    private String lastReadAddress = "";
    private String lastReadValue = "";
    private String lastReadType = "";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_modbus_rtu_demo);
        
        // 设置返回按钮
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setTitle("Modbus RTU 串口通信");
        }
        
        // 初始化控件
        initViews();
        
        // 设置按钮点击事件
        setupListeners();
        
        // 设置TextView可滚动
        tvLog.setMovementMethod(new android.text.method.ScrollingMovementMethod());
        
        // 添加触摸监听，阻止父ScrollView拦截TextView的滚动事件
        tvLog.setOnTouchListener((v, event) -> {
            // 判断是否是垂直滚动操作
            boolean isScrolling = tvLog.canScrollVertically(1) || tvLog.canScrollVertically(-1);
            
            // 当用户触摸TextView且有滚动能力时，阻止父View拦截触摸事件
            v.getParent().requestDisallowInterceptTouchEvent(isScrolling);
            
            // 返回false让TextView自己处理触摸事件
            return false;
        });
    }
    
    private void initViews() {
        // 串口配置
        spSerialPort = findViewById(R.id.sp_serial_port);
        spBaudRate = findViewById(R.id.sp_baud_rate);
        etDataBits = findViewById(R.id.et_data_bits);
        etStopBits = findViewById(R.id.et_stop_bits);
        etParity = findViewById(R.id.et_parity);
        
        // Modbus操作
        etReadAddress = findViewById(R.id.et_read_address);
        etReadCount = findViewById(R.id.et_read_count);
        etReadUnitId = findViewById(R.id.et_read_unit_id);
        etWriteAddress = findViewById(R.id.et_write_address);
        etWriteValue = findViewById(R.id.et_write_value);
        etWriteUnitId = findViewById(R.id.et_write_unit_id);
        
        // 按钮
        btnConnect = findViewById(R.id.btn_connect);
        btnDisconnect = findViewById(R.id.btn_disconnect);
        btnRead = findViewById(R.id.btn_read);
        btnWrite = findViewById(R.id.btn_write);
        btnClearLog = findViewById(R.id.btn_clear_log);
        
        // 日志
        tvLog = findViewById(R.id.tv_log);
        
        // 设置串口路径下拉框
        ArrayAdapter<String> serialPortAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_item, SERIAL_PORT_PATHS);
        serialPortAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spSerialPort.setAdapter(serialPortAdapter);
        
        // 设置波特率下拉框
        ArrayAdapter<Integer> baudRateAdapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_item, BAUD_RATES);
        baudRateAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spBaudRate.setAdapter(baudRateAdapter);
        
        // 默认选择9600波特率（ZN5X默认设置）
        for (int i = 0; i < BAUD_RATES.length; i++) {
            if (BAUD_RATES[i] == 9600) {
                spBaudRate.setSelection(i);
                break;
            }
        }
        
        // 设置初始值，匹配ZN5X高速采集仪表的默认设置
        etDataBits.setText("8");        // 数据位
        etStopBits.setText("1");        // 停止位 
        etParity.setText("0");          // 无校验位
        etReadCount.setText("1");       // 读取数量
        etReadUnitId.setText("1");      // 设备地址为1
        etWriteUnitId.setText("1");     // 设备地址为1
        
        // 添加提示信息
        tvLog.setText("ZN5X高速采集仪表默认参数:\n" +
                "- RS-485接口\n" +
                "- 波特率: 9600 bps\n" +
                "- 数据位: 8\n" +
                "- 停止位: 1\n" +
                "- 无校验位(0)\n" +
                "- Modbus-RTU协议\n" +
                "- 设备地址: 1\n\n");
    }
    
    private void setupListeners() {
        // 连接按钮
        btnConnect.setOnClickListener(v -> connectSerialPort());
        
        // 断开按钮
        btnDisconnect.setOnClickListener(v -> disconnectSerialPort());
        
        // 读取按钮
        btnRead.setOnClickListener(v -> readFromModbus());
        
        // 写入按钮
        btnWrite.setOnClickListener(v -> writeToModbus());
        
        // 清空日志按钮
        btnClearLog.setOnClickListener(v -> tvLog.setText(""));
    }
    
    /**
     * 连接到串口设备
     */
    private void connectSerialPort() {
        String serialPort = spSerialPort.getSelectedItem().toString();
        int baudRate = (Integer) spBaudRate.getSelectedItem();
        
        int dataBits = getIntFromEditText(etDataBits, 8);
        int stopBits = getIntFromEditText(etStopBits, 1);
        int parity = getIntFromEditText(etParity, 0);
        
        logMessage("尝试连接到串口: " + serialPort + ", 波特率: " + baudRate +
                ", 数据位: " + dataBits + ", 停止位: " + stopBits + ", 校验位: " + parity);
        
        // 创建数据监听器
        PlcDataListener listener = new PlcDataListener() {
            @Override
            public void onDataReceived(Object data, String dataType, String plcDataA) {
                String valueStr;
                
                if (data instanceof boolean[]) {
                    boolean[] boolArray = (boolean[]) data;
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < boolArray.length; i++) {
                        sb.append(boolArray[i] ? "1" : "0");
                        if (i < boolArray.length - 1) {
                            sb.append(", ");
                        }
                    }
                    valueStr = sb.toString();
                } else if (data instanceof int[]) {
                    int[] intArray = (int[]) data;
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < intArray.length; i++) {
                        sb.append(intArray[i]);
                        if (i < intArray.length - 1) {
                            sb.append(", ");
                        }
                    }
                    valueStr = sb.toString();
                } else {
                    valueStr = String.valueOf(data);
                }
                
                // 保存最近读取的数据
                lastReadAddress = plcDataA;
                lastReadValue = valueStr;
                lastReadType = dataType;
                
                // 记录日志
                String dataTypeDesc;
                switch (dataType) {
                    case "coil":
                        dataTypeDesc = "线圈";
                        break;
                    case "discrete_input":
                        dataTypeDesc = "离散输入";
                        break;
                    case "holding_register":
                    case "register_write":
                        dataTypeDesc = "保持寄存器";
                        break;
                    case "input_register":
                        dataTypeDesc = "输入寄存器";
                        break;
                    case "coil_write":
                        dataTypeDesc = "线圈写入";
                        break;
                    default:
                        dataTypeDesc = dataType;
                }
                
                logMessage("收到数据 - 类型: " + dataTypeDesc + ", 地址: " + plcDataA + ", 值: " + valueStr);
            }
            
            @Override
            public void onError(String error) {
                logMessage("错误: " + error);
            }
        };
        
        // 创建Modbus RTU帮助类
        modbusHelper = new ModbusRtuHelper(serialPort, baudRate, listener);
        
        // 设置串口参数
        modbusHelper.setSerialPortParams(dataBits, stopBits, parity);
        
        // 设置超时时间为2秒
        modbusHelper.setTimeout(2000);
        
        // 连接到串口设备
        modbusHelper.connectAsync(() -> {
            if (modbusHelper.isConnected()) {
                runOnUiThread(() -> {
                    updateConnectionStatus(true);
                    logMessage("成功连接到串口设备");
                    showToast("连接成功");
                });
            } else {
                runOnUiThread(() -> {
                    updateConnectionStatus(false);
                    logMessage("连接串口设备失败");
                    showToast("连接失败");
                });
            }
        });
    }
    
    /**
     * 断开串口连接
     */
    private void disconnectSerialPort() {
        if (modbusHelper != null) {
            modbusHelper.disconnect();
            updateConnectionStatus(false);
            logMessage("已断开串口连接");
        }
    }
    
    /**
     * 从Modbus设备读取数据
     */
    private void readFromModbus() {
        if (!isConnected) {
            showToast("请先连接串口设备");
            return;
        }
        
        String addressStr = etReadAddress.getText().toString().trim();
        if (TextUtils.isEmpty(addressStr)) {
            showToast("请输入要读取的地址");
            return;
        }
        
        int count = getIntFromEditText(etReadCount, 1);
        int unitId = getIntFromEditText(etReadUnitId, 1);
        
        logMessage("开始读取 - 地址: " + addressStr + ", 数量: " + count + ", 设备ID: " + unitId);
        
        // 解析Modbus地址
        ModbusRtuHelper.ModbusAddressInfo addressInfo = ModbusRtuHelper.parseModbusAddress(addressStr);
        
        if (addressInfo == null) {
            showToast("无效的Modbus地址格式");
            return;
        }
        
        // 根据地址类型读取不同的数据
        try {
            switch (addressInfo.type) {
                case COIL:
                    modbusHelper.readCoils(addressInfo.address, count, unitId);
                    break;
                case DISCRETE_INPUT:
                    modbusHelper.readDiscreteInputs(addressInfo.address, count, unitId);
                    break;
                case INPUT_REGISTER:
                    modbusHelper.readRegisters(addressInfo.address, count, unitId, true);
                    break;
                case HOLDING_REGISTER:
                    modbusHelper.readRegisters(addressInfo.address, count, unitId, false);
                    break;
            }
        } catch (Exception e) {
            logMessage("读取失败: " + e.getMessage());
            showToast("读取失败: " + e.getMessage());
        }
    }
    
    /**
     * 向Modbus设备写入数据
     */
    private void writeToModbus() {
        if (!isConnected) {
            showToast("请先连接串口设备");
            return;
        }
        
        String addressStr = etWriteAddress.getText().toString().trim();
        if (TextUtils.isEmpty(addressStr)) {
            showToast("请输入要写入的地址");
            return;
        }
        
        String valueStr = etWriteValue.getText().toString().trim();
        if (TextUtils.isEmpty(valueStr)) {
            showToast("请输入要写入的值");
            return;
        }
        
        int unitId = getIntFromEditText(etWriteUnitId, 1);
        
        logMessage("开始写入 - 地址: " + addressStr + ", 值: " + valueStr + ", 设备ID: " + unitId);
        
        // 解析Modbus地址
        ModbusRtuHelper.ModbusAddressInfo addressInfo = ModbusRtuHelper.parseModbusAddress(addressStr);
        
        if (addressInfo == null) {
            showToast("无效的Modbus地址格式");
            return;
        }
        
        // 根据地址类型写入不同的数据
        try {
            boolean success = false;
            
            switch (addressInfo.type) {
                case COIL:
                    // 线圈写入
                    boolean boolValue;
                    if ("0".equals(valueStr) || "false".equalsIgnoreCase(valueStr) || "off".equalsIgnoreCase(valueStr)) {
                        boolValue = false;
                    } else if ("1".equals(valueStr) || "true".equalsIgnoreCase(valueStr) || "on".equalsIgnoreCase(valueStr)) {
                        boolValue = true;
                    } else {
                        showToast("无效的线圈值，请使用0/1或true/false");
                        return;
                    }
                    success = modbusHelper.writeSingleCoil(addressInfo.address, boolValue, unitId);
                    break;
                    
                case HOLDING_REGISTER:
                    // 保持寄存器写入
                    try {
                        int intValue = Integer.parseInt(valueStr);
                        success = modbusHelper.writeSingleRegister(addressInfo.address, intValue, unitId);
                    } catch (NumberFormatException e) {
                        showToast("无效的寄存器值，请输入整数");
                        return;
                    }
                    break;
                    
                default:
                    showToast("不支持写入的寄存器类型: " + addressInfo.typeDescription);
                    return;
            }
            
            if (!success) {
                showToast("写入失败");
            }
        } catch (Exception e) {
            logMessage("写入失败: " + e.getMessage());
            showToast("写入失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新连接状态和UI
     */
    private void updateConnectionStatus(boolean connected) {
        isConnected = connected;
        
        // 更新按钮状态
        btnConnect.setEnabled(!connected);
        btnDisconnect.setEnabled(connected);
        btnRead.setEnabled(connected);
        btnWrite.setEnabled(connected);
        
        // 更新串口配置控件状态
        spSerialPort.setEnabled(!connected);
        spBaudRate.setEnabled(!connected);
        etDataBits.setEnabled(!connected);
        etStopBits.setEnabled(!connected);
        etParity.setEnabled(!connected);
    }
    
    /**
     * 从EditText获取整数值
     */
    private int getIntFromEditText(EditText editText, int defaultValue) {
        try {
            String text = editText.getText().toString().trim();
            if (!TextUtils.isEmpty(text)) {
                return Integer.parseInt(text);
            }
        } catch (NumberFormatException e) {
            Log.e(TAG, "解析整数失败: " + e.getMessage(), e);
        }
        return defaultValue;
    }
    
    /**
     * 记录日志消息
     */
    private void logMessage(String message) {
        runOnUiThread(() -> {
            // 添加时间戳
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
            String timestamp = sdf.format(new Date());
            
            // 添加到日志
            String logEntry = timestamp + " - " + message + "\n";
            tvLog.append(logEntry);
            
            // 滚动到底部
            final int scrollAmount = tvLog.getLayout().getLineTop(tvLog.getLineCount()) - tvLog.getHeight();
            if (scrollAmount > 0) {
                tvLog.scrollTo(0, scrollAmount);
            } else {
                tvLog.scrollTo(0, 0);
            }
        });
    }
    
    /**
     * 显示Toast消息
     */
    private void showToast(String message) {
        runOnUiThread(() -> Toast.makeText(this, message, Toast.LENGTH_SHORT).show());
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        // 断开连接
        if (modbusHelper != null) {
            modbusHelper.disconnect();
        }
    }
} 